;  PROGRAM:  PROTECT
;  VERSION:  2.0
;  DATE:  16 Jan 83
;  AUTHOR:  RICHARD CONN
;  PREVIOUS VERSIONS:  1.3 (6 Jan 83), 1.2 (7 Dec 82), 1.1 (10 NOV 82)
;  PREVIOUS VERSION:  PROTECT.ASM Version 1.0 (26 OCT 81)
VERS	equ	20

;
;	This program is Copyright (c) 1982, 1983 by Richard Conn
;	All Rights Reserved
;
;	ZCPR2 and its utilities, including this one, are released
; to the public domain.  Anyone who wishes to USE them may do so with
; no strings attached.  The author assumes no responsibility or
; liability for the use of ZCPR2 and its utilities.
;
;	The author, Richard Conn, has sole rights to this program.
; ZCPR2 and its utilities may not be sold without the express,
; written permission of the author.
;


;
;  PROTECT Command --
;	PROTECT is used to set the file protection and tag attribute bits
; for CP/M 2.x files in the ZCPR2 environment.  It is invoked via command
; lines of the following forms:
;		PROTECT dir:afn1,dir:afn2,... keys	<-- Set unconditionally
;		PROTECT dir:afn1,... keys I		<-- Inspect Mode
;		PROTECT dir:afn1,... C			<-- Set each ufn
;
;	In the above examples, the reference 'keys' is a string of zero or
; more characters which may be any of the following:
;
;		A <-- Set AR Attribute
;		R <-- Set R/O Attribute (no R sets R/W)
;		S <-- Set SYS Attribute (no S sets Non-System)
;		n <-- Set Tag Attribute (1 <= n <= 8)
;
;	Examples:
;		PROTECT *.COM RS	<-- Sets all COM files to R/O SYStem
;		PROTECT *.COM RSI	<-- Same, with user approval
;		PROTECT *.COM C		<-- Allows user to specify for each
;		PROTECT MYPROG.COM 1R	<-- Sets Tag Bit 1 and R/O Attribute
;

FALSE	EQU	0
TRUE	EQU	NOT FALSE

ESIZE	EQU	16	; SIZE OF DIR ENTRY (FROM SYSLIB DIRF ROUTINE)

	EXT	DIRF	; DIRECTORY PROCESSOR

	EXT	ZGPINS	; INIT BUFFERS
	EXT	ZFNAME	; FILE NAME PROCESSOR

	EXT	BBLINE	; INPUT LINE EDITOR
	EXT	INITFCB	; INIT FCB
	EXT	BDOS	; BDOS ENTRY
	EXT	RETUD	; RETURN CURRENT USER/DISK
	EXT	PUTUD	; SAVE CURRENT USER/DISK
	EXT	GETUD	; RESTORE CURRENT USER/DISK
	EXT	MOVEB	; COPY ROUTINE
	EXT	PHLDC	; PRINT HL AS DECIMAL CHARS
	EXT	PRINT	; PRINT ROUTINE
	EXT	COUT	; CONSOLE OUTPUT ROUTINE
	EXT	CIN	; CONSOLE INPUT ROUTINE
	EXT	CAPS	; CAPITALIZE ROUTINE
	EXT	CRLF	; NEW LINE ROUTINE
	EXT	FILLB	; FILL ROUTINE
	EXT	CODEND	; CODE END COMPUTATION ROUTINE

;
;  CP/M EQUATES
;
CPM	EQU	0	; WARM BOOT
FCB	EQU	5CH	; FCB
BUFF	EQU	80H	; INPUT LINE BUFFER
CR	EQU	13	; <CR>
LF	EQU	10	; <LF>

;
;  Branch to Start of Program
;
	JMP	START

;
;******************************************************************
;
;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
;
;	This data block precisely defines the data format for
; initial features of a ZCPR2 system which are required for proper
; initialization of the ZCPR2-Specific Routines in SYSLIB.
;

;
;  EXTERNAL PATH DATA
;
EPAVAIL:
	DB	0FFH	; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
EPADR:
	DW	40H	; ADDRESS OF EXTERNAL PATH IF AVAILABLE

;
;  INTERNAL PATH DATA
;
INTPATH:
	DB	0,0	; DISK, USER FOR FIRST PATH ELEMENT
			; DISK = 1 FOR A, '$' FOR CURRENT
			; USER = NUMBER, '$' FOR CURRENT
	DB	0,0
	DB	0,0
	DB	0,0
	DB	0,0
	DB	0,0
	DB	0,0
	DB	0,0	; DISK, USER FOR 8TH PATH ELEMENT
	DB	0	; END OF PATH

;
;  MULTIPLE COMMAND LINE BUFFER DATA
;
MCAVAIL:
	DB	0FFH	; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
MCADR:
	DW	0FF00H	; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE

;
;  DISK/USER LIMITS
;
MDISK:
	DB	4	; MAXIMUM NUMBER OF DISKS
MUSER:
	DB	31	; MAXIMUM USER NUMBER

;
;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
;
DOK:
	DB	0FFH	; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
UOK:
	DB	0FFH	; ALLOW USER CHANGE? (0=NO, 0FFH=YES)

;
;  PRIVILEGED USER DATA
;
PUSER:
	DB	10	; BEGINNING OF PRIVILEGED USER AREAS
PPASS:
	DB	'chdir',0	; PASSWORD FOR MOVING INTO PRIV USER AREAS
	DS	41-($-PPASS)	; 40 CHARS MAX IN BUFFER + 1 for ending NULL

;
;  CURRENT USER/DISK INDICATOR
;
CINDIC:
	DB	'$'	; USUAL VALUE (FOR PATH EXPRESSIONS)

;
;  DMA ADDRESS FOR DISK TRANSFERS
;
DMADR:
	DW	80H	; TBUFF AREA

;
;  NAMED DIRECTORY INFORMATION
;
NDRADR:
	DW	00000H	; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
NDNAMES:
	DB	64	; MAX NUMBER OF DIRECTORY NAMES
DNFILE:
	DB	'NAMES   '	; NAME OF DISK NAME FILE
	DB	'DIR'		; TYPE OF DISK NAME FILE

;
;  REQUIREMENTS FLAGS
;
EPREQD:
	DB	0FFH	; EXTERNAL PATH?
MCREQD:
	DB	0FFH	; MULTIPLE COMMAND LINE?
MXREQD:
	DB	0FFH	; MAX USER/DISK?
UDREQD:
	DB	0FFH	; ALLOW USER/DISK CHANGE?
PUREQD:
	DB	0FFH	; PRIVILEGED USER?
CDREQD:
	DB	0FFH	; CURRENT INDIC AND DMA?
NDREQD:
	DB	0FFH	; NAMED DIRECTORIES?
Z2CLASS:
	DB	0	; CLASS 0
	DB	'ZCPR2'
	DS	10	; RESERVED

;
;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
;
;******************************************************************
;

;
;  Start of Program
;
START:
	LXI	H,0	; GET STACK PTR
	DAD	SP
	SHLD	STACK	; SAVE IT
	LXI	SP,STACK	; SET SP
	CALL	PUTUD	; SAVE CURRENT USER/DISK AWAY
	MVI	A,0FFH	; SET DEFAULT USER
	STA	USER

	CALL	ZGPINS	; INIT BUFFERS
	CALL	PRINT
	DB	'PROTECT  Version '
	DB	VERS/10+'0','.',(VERS MOD 10)+'0',0
	LDA	FCB+1	; GET FIRST CHAR OF FILE NAME
	CPI	' '	; NO FILE SPEC?
	JZ	HELP
	CPI	'/'	; OPTION CAUGHT?
	JNZ	ECONT

;  PRINT HELP INFORMATION
HELP:
	CALL	PRINT
	DB	CR,LF,'PROTECT Command --'
	DB	CR,LF,'  PROTECT dir:filename.typ,dir:fn.ft,dir:fn.ft,... ooo'
	DB	CR,LF,LF,'d is disk, u is user, and o is one or more option '
	DB	'letters.'
	DB	CR,LF,'If one or more options are specified, the o MUST be '
	DB	'preceded by a space.'
	DB	CR,LF,'Nothing is required, and wild cards (?,*) are '
	DB	CR,LF,'permitted.  o is optional, and valid options are -'
	DB	CR,LF,'	C -- Control Mode (Allow user to set each file)'
	DB	CR,LF,'	I -- Inspect Mode (Give user option to set att)'
	DB	CR,LF,'	n -- 1 <= n <= 8; Set Tag Attribute'
	DB	CR,LF,'	A -- Set AR (Archive) Attribute'
	DB	CR,LF,'	R -- Set R/O Attribute (no R sets R/W)'
	DB	CR,LF,'	S -- Set SYS Attribute (no S sets Non-System)'
	DB	CR,LF,'dir: is a named directory or the form du:.'
	DB	CR,LF,'Named Directories are ',0
	LDA	NDREQD	; NAMES REQUIRED?
	ORA	A	; 0=NO
	JNZ	HELP1
	CALL	PRINT
	DB	'NOT ',0
HELP1:
	CALL	PRINT
	DB	'Permitted in this Version of PROTECT'
	DB	CR,LF,'If u is omitted, current user is assumed, as with d.'
	DB	CR,LF,LF,'Special forms are:'
	DB	CR,LF,'	PROTECT dir:	<-- Prot all files in named directory'
	DB	CR,LF,'	PROTECT du:	<-- Prot all files in disk d, user u'
	DB	CR,LF,'	PROTECT u:	<-- Prot all files in user u on '
	DB	'current disk'
	DB	CR,LF,'	PROTECT d:	<-- Prot all files on disk d in '
	DB	'current user'
	DB	0

;  RETURN TO OS
RETURN:
	LHLD	STACK	; GET OLD STACK
	SPHL		; SET IT
	RET

;  USER CHANGE NOT ALLOWED ERROR
UNOK:
	CALL	PRINT
	DB	CR,LF,'User Number Change Not Allowed -- Aborting',0
	JMP	RETURN

;  DISK CHANGE NOT ALLOWED ERROR
DNOK:
	CALL	PRINT
	DB	CR,LF,'Disk Change Not Allowed -- Aborting',0
	JMP	RETURN

;  PLACE ZERO AT END OF BUFFER
ECONT:
	LXI	H,BUFF	; PT TO BUFFER
	MOV	A,M	; GET COUNT
	INX	H	; PT TO FIRST CHAR
	ADD	L	; PT TO END OF BUFFER
	MOV	L,A
	MOV	A,H
	ACI	0
	MOV	H,A
	MVI	M,0

;  COPY BUFFER INTO TEMP BUFFER
	LXI	H,BUFF	; PT TO BUFFER
	MOV	B,M	; GET CHAR COUNT
	INX	H	; PT TO FIRST CHAR
	INR	B	; ADD ENDING 0
	LXI	D,CMDLNE	; PT TO CMDLNE BUFFER
	CALL	MOVEB	; COPY INTO COMMAND LINE BUFFER

;  EXTRACT FLAGS IF PRESENT
	XRA	A	; SET NO INSPECT, NO R/O, NO ARCH, AND NO SYSTEM FILES
	STA	INSPECT
	STA	READONLY
	STA	SYSTEM
	STA	ARCHIVE
	STA	CONTROL	; SET NO CONTROL MODE
	MVI	B,8	; CLEAR TAG BITS
	LXI	H,TAGS
	CALL	FILLB
	LXI	H,0	; SET FILE COUNT
	SHLD	FILECNT
	LXI	H,CMDLNE	; PT TO BUFFER
;  SKIP TO FILE NAME STRING
SBLANK:
	MOV	A,M	; SKIP TO NON-BLANK
	CPI	' '	; <SP>?
	JNZ	SBL1
	INX	H	; PT TO NEXT CHAR
	JMP	SBLANK
;  SKIP TO END OF FILE NAME STRING
SBL1:
	MOV	A,M	; SKIP TO <SP> OR EOL
	ORA	A	; DONE?
	JZ	OPT
	CPI	' '	; <SP>
	JZ	OPT
	INX	H	; PT TO NEXT
	JMP	SBL1
;  CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO
OPT:
	CPI	'/'	; OPTION CHAR?
	JNZ	OPTION
	INX	H	; SKIP SLASH
;  PROCESS LIST OF OPTIONS
OPTION:
	MOV	A,M	; GET BYTE
	ORA	A	; DONE?
	JZ	DSPEC
	INX	H	; PT TO NEXT CHAR
	CPI	' '	; SKIP OVER SPACES
	JZ	OPTION
	CPI	'/'	; IF OPTION LETTER, OBVIOUS ERROR, SO HELP
	JZ	HELP
	CPI	'1'	; DIGIT?
	JC	HELP
	CPI	'8'+1	; IN RANGE?
	JC	OPTNUM
	CPI	'C'	; CONTROL?
	JZ	OPTCTRL
	CPI	'I'	; INSPECT?
	JZ	OPTINS
	CPI	'A'	; ARCHIVE
	JZ	OPTAR
	CPI	'R'	; READ/ONLY?
	JZ	OPTRO
	CPI	'S'	; SYSTEM FILES?
	JNZ	HELP
	MVI	A,80H	; SET FOR SYS FILES
	STA	SYSTEM
	JMP	OPTION
OPTNUM:
	SUI	'1'	; ADJUST '1' TO '8' TO 0-7
	PUSH	H	; SAVE PTR
	MOV	E,A	; VALUE IN DE
	MVI	D,0
	LXI	H,TAGS	; PT TO TAG BUFFER
	DAD	D	; PT TO ELEMENT
	MVI	M,80H	; SELECT ELEMENT
	POP	H	; GET PTR TO NEXT CHAR
	JMP	OPTION
OPTCTRL:
	MVI	A,0FFH	; CONTROL MODE
	STA	CONTROL
	JMP	OPTION
OPTINS:
	MVI	A,0FFH	; INSPECT
	STA	INSPECT
	JMP	OPTION
OPTAR:
	MVI	A,80H	; SET ARCHIVE
	STA	ARCHIVE
	JMP	OPTION
OPTRO:
	MVI	A,80H	; SET R/O
	STA	READONLY
	JMP	OPTION

;  EXTRACT DISK, USER, AND FILE NAME INFORMATION
DSPEC:
	LXI	H,CMDLNE-1	; PT TO BEFORE FIRST BYTE
DSPEC0:
	INX	H	; PT TO BYTE
	MOV	A,M	; GET BYTE
	ORA	A	; DONE?
	JZ	HELP
	CPI	' '	; <SP>?
	JZ	DSPEC0
;
;  MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS
;    HL PTS TO FIRST BYTE OF NEXT FILE SPEC
;
DSPEC1:
	CALL	GETUD	; RESET USER IF NECESSARY
	LXI	D,FCB	; PT TO FCB IN DE, PT TO FIRST CHAR OF FILE NAME IN HL

	PUSH	H	; SAVE HL PTR
	CALL	CODEND	; GET ADDRESS OF SCRATCH AREA
	MOV	B,H	; ADDRESS IN BC
	MOV	C,L
	POP	H

	CALL	ZFNAME	; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER
	JZ	DERR	; ERROR HANDLER

	SHLD	NEXTCH	; SAVE PTR TO DELIMITER WHICH ENDED SCAN
	MOV	A,C	; GET NEW USER
	STA	USER	; SAVE IT
	MOV	A,B	; SAVE POSSIBLE DRIVE SPEC
	CPI	0FFH	; CURRENT DISK?
	JZ	USPEC
	LDA	MDISK	; GET MAX DISK NUMBER
	DCR	B	; ADJUST TO WITHIN BOUNDS 0-15
	CMP	B	; WITHIN BOUNDS?
	MOV	A,B	; GET DISK NUMBER IN A
	JNC	DSPEC2
DERR:
	CALL	PRINT
	DB	CR,LF,'Invalid Drive or User Specification',0
	JMP	RETURN

;  LOG IN SPECIFIED DISK
DSPEC2:
	PUSH	B	; SAVE BC
	MOV	E,A	; DISK NUMBER IN E
	LDA	DOK	; OK TO DO SO?
	ORA	A	; 0=NO
	JZ	DNOK	; NOT ALLOWED ABORT
	MVI	C,14	; LOG IN DISK
	CALL	BDOS
	POP	B	; GET BC

;  CHECK FOR USER NUMBER
USPEC:
	MOV	A,C	; GET NEW USER NUMBER
	CPI	0FFH	; DEFAULT USER?
	JZ	PROT
	CPI	'?'	; ALL USERS NOT ALLOWED?
	JZ	UERR
	LDA	MUSER	; GET MAX USER NUMBER
	CMP	C
	MOV	A,C	; USER NUMBER IN A
	JNC	ULOG
UERR:
	CALL	PRINT
	DB	CR,LF,'Invalid User Number',0
	JMP	RETURN
ULOG:
	MOV	E,A	; USER NUMBER IN E
	LDA	UOK	; ALLOWED?
	ORA	A	; 0=NO
	JZ	UNOK	; DISALLOWED AND ABORT
	MVI	C,32	; SELECT USER
	CALL	BDOS

;  LOAD DIRECTORY AND PROTECT FILES
PROT:
	CALL	CODEND	; PT TO END OF CODE
	CALL	RETUD	; GET CURRENT USER
	MOV	A,C	; CURRENT USER IN A
	ORI	0C0H	; SELECT NON-SYS AND SYS FILES IN CURRENT USER
	LXI	D,FCB	; PT TO FCB
	CALL	DIRF	; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE

;  PROT DIR FILES; HL PTS TO FIRST FILE, BC=FILE COUNT
	CALL	PROTFILES

;  CHECK FOR NEXT FILE SPEC
	LHLD	NEXTCH	; GET PTR
	MOV	A,M	; GET DELIM
	CPI	','	; ANOTHER FILE?
	JNZ	PROTDONE
	INX	H	; PT TO CHAR AFTER COMMA
	JMP	DSPEC1	; CONTINUE PROCESSING

;  PROT COMPLETE -- PRINT COUNT AND EXIT
PROTDONE:
	CALL	PRCOUNT	; PRINT FILE COUNT
	JMP	RETURN

;  PROT SELECTED FILES
PROTFILES:
	MOV	A,B	; CHECK FOR ANY FILES LOADED
	ORA	C
	RZ

;  PRINT FILE NAME
PROTLP:
	PUSH	B	; SAVE ENTRY COUNT
	CALL	CRLF	; NEW LINE
	PUSH	H	; SAVE PTR TO FCB
	INX	H	; PT TO FILE NAME
	MVI	B,8	; PRINT NAME
	CALL	PRNT
	MVI	A,'.'	; DECIMAL
	CALL	COUT
	MVI	B,3	; PRINT TYPE
	CALL	PRNT
	POP	H	; GET PTR

;  CHECK FOR CONTROL MODE AND PERFORM CONTROL FUNCTION IF SET
	LDA	CONTROL	; GET FLAG
	ORA	A	; NZ=YES
	JNZ	PROTCTRL

;  CHECK FOR INSPECTION AND INSPECT IF SET
	LDA	INSPECT	; GET FLAG
	ORA	A	; 0=NO
	JZ	DOIT

;  PROMPT USER FOR PROTECT
	CALL	PROTQ	; PROT QUESTION
	CPI	'Q'	; QUIT?
	JZ	QUIT
	CPI	'Y'	; YES?
	JZ	DOIT

;  DON'T PROTECT FILE
NODO:
	CALL	PRINT
	DB	'  ++ NO Attribute Change ++',0
	JMP	PROTTEST

;  PROMPT USER FOR PROT
PROTQ:
	CALL	PRINT	; PRINT PROMPT
	DB	' -- Protect (Y/N/Q=Quit/other=N)? ',0
	CALL	CIN	; GET RESPONSE
	CALL	CAPS	; CAPITALIZE
	CALL	COUT	; ECHO
	RET

;  CONTROL FUNCTION -- ALLOW USER TO SET BITS AS HE DESIRES
PROTCTRL:
	PUSH	H	; SAVE PTR TO FILE
	XRA	A	; A=0
	STA	READONLY	; CLEAR R/O, SYS, ARCHIVE, AND TAGS
	STA	SYSTEM
	STA	ARCHIVE
	LXI	H,TAGS
	MVI	B,8
	CALL	FILLB
	CALL	PRINT
	DB	' -- Attributes (? for Help)? ',0
	MVI	A,0FFH	; CAPITALIZE
	CALL	BBLINE	; INPUT LINE FROM USER
	CALL	CRLF	; NEW LINE
	MVI	B,80H	; MSB SET
PCTRL:
	MOV	A,M	; GET ATTRIBUTE FLAG
	ORA	A	; DONE?
	JZ	PDOIT	; DO PROTECTION THEN
	INX	H	; PT TO NEXT
	CPI	' '	; SKIP <SP>
	JZ	PCTRL
	CPI	'Q'	; QUIT?
	JZ	QUIT
	CPI	'A'	; ARCHIVE?
	JZ	PCTRLA
	CPI	'S'	; SYSTEM?
	JZ	PCTRLS
	CPI	'R'	; R/O?
	JZ	PCTRLR
	CPI	'1'	; DIGIT?
	JC	PCTRLH	; HELP IF NOT
	CPI	'8'+1	; RANGE?
	JC	PCTRLN	; DO NUMBER
PCTRLH:
	CALL	PRINT
	DB	CR,LF,'  You may issue the Q command to quit or select any'
	DB	CR,LF,'    arrangement of attributes that you desire.'
	DB	CR,LF,'  Attributes may be specified as follows --'
	DB	CR,LF,'		A = Archive, R = R/O, S = SYS, 1-8 = Tags'
	DB	CR,LF,0
	POP	H	; GET FCB PTR
	POP	B	; GET ENTRY COUNT
	JMP	PROTLP	; PROCESS AGAIN
PCTRLA:
	MOV	A,B	; GET FLAG
	STA	ARCHIVE	; SET FLAG
	JMP	PCTRL
PCTRLS:
	MOV	A,B	; GET FLAG
	STA	SYSTEM	; SET FLAG
	JMP	PCTRL
PCTRLR:
	MOV	A,B	; GET AND SET FLAG
	STA	READONLY
	JMP	PCTRL
PCTRLN:
	PUSH	H
	SUI	'1'	; CONVERT TO OFFSET
	MOV	E,A	; OFFSET IN DE
	MVI	D,0
	LXI	H,TAGS	; SET TAG
	DAD	D
	MOV	M,B	; SET BIT
	POP	H
	JMP	PCTRL	; CONTINUE

;  QUIT PROTECT PROGRAM
QUIT:
	CALL	PRCOUNT	; PRINT COUNT OF FILES PROTECTED
	CALL	PRINT
	DB	CR,LF,'  ++ QUIT -- Returning to CP/M ++',0
	JMP	RETURN

;  PROT FILE, BUT GET PTR FIRST
PDOIT:
	POP	H	; GET PTR

;  PROT FILE
DOIT:
	PUSH	H
	LXI	D,PROTFCB	; COPY TARGET FILE INTO PROTECT'S FCB
	MVI	B,16	; 16 BYTES
	CALL	MOVEB	; COPY
	LXI	H,TAGS	; SET TAG BITS NOW
	INX	D	; PT TO FIRST TAG BIT
	MVI	B,8	; 8 TAG BITS
DOITL:
	LDAX	D	; GET BYTE FROM PROT FCB
	ANI	7FH	; MASK OUT OLD MSB
	ORA	M	; OR IN TAG BIT
	STAX	D	; PUT BYTE BACK
	INX	H	; PT TO NEXT
	INX	D
	DCR	B	; COUNT DOWN
	JNZ	DOITL
	LDA	READONLY	; GET R/O BIT
	MOV	B,A	; SAVE IN B
	LDAX	D	; GET BYTE
	ANI	7FH	; MASK OUT OLD MSB
	ORA	B	; OR IN NEW MSB
	STAX	D	; PUT IT BACK
	INX	D	; PT TO SYS BIT
	LDA	SYSTEM	; GET SYS BIT
	MOV	B,A	; SAVE IT
	LDAX	D	; GET BYTE
	ANI	7FH	; MASK OUT OLD MSB
	ORA	B	; MASK IN NEW MSB
	STAX	D	; PUT IT BACK
	INX	D	; PT TO ARCHIVE BIT
	LDA	ARCHIVE	; GET ARCHIVE BIT
	MOV	B,A	; SAVE IT
	LDAX	D	; GET BYTE
	ANI	7FH	; MASK OUT OLD MSB
	ORA	B	; MASK IN NEW MSB
	STAX	D	; PUT IT BACK
	LXI	D,PROTFCB	; PT TO FCB
	CALL	INITFCB	; INIT IT
	MVI	C,30	; SET FILE ATTRIBUTES
	CALL	BDOS
	CALL	PRINT
	DB	' Set to ',0
	LXI	H,PROTFCB+1
	MVI	B,8	; 8 TAGS
	MVI	C,'1'	; SET DIGIT
PATTL1:
	MOV	A,M	; GET BYTE
	ANI	80H	; PRINT ATT?
	JZ	PATTL2
	MOV	A,C	; GET DIGIT
	CALL	COUT
PATTL2:
	INR	C	; INCREMENT DIGIT
	INX	H	; PT TO NEXT
	DCR	B	; COUNT DOWN
	JNZ	PATTL1
	MOV	A,M	; GET R/O BYTE
	ANI	80H	; MASK IT
	JZ	PATTL3
	CALL	PRINT
	DB	' R/O ',0
	JMP	PATTL4
PATTL3:
	CALL	PRINT
	DB	' R/W ',0
PATTL4:
	INX	H	; PT TO SYS BYTE
	MOV	A,M	; GET SYS BYTE
	ANI	80H	; MASK IT
	JZ	PATTL5
	CALL	PRINT
	DB	'SYS',0
	JMP	PATTL6
PATTL5:
	CALL	PRINT
	DB	'DIR',0
PATTL6:
	INX	H	; PT TO ARCHIVE BYTE
	MOV	A,M	; GET ARCH BYTE
	ANI	80H	; MASK IT
	JZ	PATTL7
	CALL	PRINT
	DB	' AR',0
PATTL7:
	LHLD	FILECNT	; INCREMENT FILE COUNT
	INX	H
	SHLD	FILECNT
	POP	H	; GET PTR TO DIRECTORY ENTRY

;  PT TO NEXT ENTRY
PROTTEST:
	LXI	D,ESIZE	; PT TO NEXT ENTRY
	DAD	D
	POP	B	; GET COUNT
	DCX	B	; COUNT DOWN
	MOV	A,B	; CHECK FOR ZERO
	ORA	C
	JNZ	PROTLP

;  RETURN TO CALLER
	RET

;
;  PRINT CHARS PTED TO BY HL FOR B BYTES
;
PRNT:
	MOV	A,M	; GET CHAR
	CALL	COUT
	INX	H	; PT TO NEXT
	DCR	B	; COUNT DOWN
	JNZ	PRNT
	RET

;
;  PRINT COUNT OF NUMBER OF FILES PROTECTED
;
PRCOUNT:
	CALL	CRLF	; NEW LINE
	CALL	PRINT
	DB	CR,LF,'++ ',0
	LHLD	FILECNT	; GET COUNT
	MOV	A,L	; CHECK FOR NONE
	ORA	H
	JZ	PRNO
	CALL	PHLDC	; PRINT DECIMAL COUNT
	JMP	PRMS
PRNO:
	CALL	PRINT
	DB	'No ',0
PRMS:
	LHLD	FILECNT	; 1 FILE PROTECTED?
	MOV	A,H	; HIGH ZERO?
	ORA	A
	JNZ	PRMULT
	MOV	A,L	; LOW ONE?
	CPI	1
	JZ	PRSING
PRMULT:
	CALL	PRINT
	DB	' Files Protected ++',0
	RET
PRSING:
	CALL	PRINT
	DB	' File  Protected ++',0
	RET

;
;  BUFFERS
;
INSPECT:
	DS	1	; INSPECT FLAG (0=NO, 0FFH=YES)
CONTROL:
	DS	1	; CONTROL FLAG (0=NO, 0FFH=YES)
ARCHIVE:
	DS	1	; ARCHIVE FLAG (0=NO, 80H=YES)
SYSTEM:
	DS	1	; SYSTEM FLAG (0=NO, 80H=YES)
READONLY:
	DS	1	; READ/ONLY FLAG (0=NO, 80H=YES)
TAGS:
	DS	8	; 8 TAG BITS
USER:
	DS	1	; NEW USER, OR 0FFH IF NO CHANGE
NEXTCH:
	DS	2	; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE
FILECNT:
	DS	2	; COUNT OF NUMBER OF FILES PROTECTED
PROTFCB:
	DS	40	; FCB FOR PROTECT
CMDLNE:
	DS	256	; ALLOW MAX SIZE OF COMMAND LINE
	DS	100	; STACK AREA
STACK:
	DS	2	; OLD STACK PTR

	END
